package zx.x.modules.app.controller;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import zx.x.modules.app.dao.OrderDao;
import zx.x.modules.app.dto.OrderDto;
import zx.x.modules.app.entity.*;
import zx.x.modules.app.pw.pw;
import zx.x.modules.app.service.*;
import zx.x.common.utils.R;
import zx.x.modules.app.task.OrderDyTask;
import zx.x.modules.app.task.OrderTask;
import zx.x.modules.app.utils.*;
import zx.x.modules.common.entity.CreativeGoodsEntity;
import zx.x.modules.common.service.CreativeGoodsService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.apache.http.HttpStatus.SC_INSUFFICIENT_STORAGE;
import static zx.x.modules.app.utils.Sc.subList;
import static zx.x.modules.app.utils.WxTkUtil.getRefundDecrypt;
import static zx.x.modules.app.utils.WxTkUtil.xmlToMap;


/**
 *
 *
 * @author x
 * @email x
 * @date 2022-10-13 09:55:21
 */
@RestController
@RequestMapping("/app/order")
public class OrderController {
    @Autowired
    OrderService orderService;
    @Autowired
    RoomAppointmentService roomAppointmentService;
    @Autowired
    OrderDao dao;
    @Autowired
    SysOrderTaskService sysOrderTaskService;
    @Autowired
    SysOrderLogService sysOrderLogService;
    @Autowired
    OrderPriceDetailsService orderPriceDetailsService; // 订单快照
    @Autowired
    ActivityRoomPriceService activityRoomPriceService;// 活动价格
    @Autowired
    MerchantRoomService merchantRoomService;
    @Autowired
    MerchantService merchantService;
    @Autowired
    MerchantWalletLogService merchantWalletLogService;
    @Autowired
    private CateringService cateringService;
    @Autowired
    private OrderJobLogService orderJobLogService;
    @Autowired
    private CreativeGoodsService creativeGoodsService;
    @Autowired
    DybService dybService;


    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(OrderDto dto) throws Exception {
        int total = orderService.getListTotal(dto);
        return R.ok().put("page", subList(orderService.selectOrderDetailedList(dto),dto.getPage(),dto.getLimit())).put("pages", dto.getPage()).put("total", total);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Integer id){
        OrderEntity order = orderService.getById(id);
        return R.ok().put("order", order);
    }

    /**
     * 酒店下单保存
     */
    @Transactional
    @RequestMapping("/jdSave")
    public R jdSave(OrderDto order) throws ParseException {
        String[] ids = order.getRoomIds().split(",");
        String[] strings = order.getYdTime().split(","); // 包含离店时间的日期
        String sjrzTime = order.getYdTime().substring(0,order.getYdTime().lastIndexOf(",")); // 实际入驻时间
        String lkTime = order.getYdTime().substring((order.getYdTime().lastIndexOf(",")+1)); // 实际离店时间
        String[] strEndIndea = sjrzTime.split(",");
        int i = 0;
        BigDecimal price = new BigDecimal(0);
        for (String id: ids) {
            // 查询预约表中是否有预定的，加二重锁
            RoomAppointmentEntity f =  roomAppointmentService.selectByYdTime(order.getYdTime(),Integer.valueOf(id));
            if (f == null){
                QueryWrapper<MerchantRoomEntity> queryRoomWrapper = new QueryWrapper<MerchantRoomEntity>();
                queryRoomWrapper.eq("id",id).eq("delete_flag","0").eq("status",0);
                MerchantRoomEntity roomObj=  merchantRoomService.getOne(queryRoomWrapper);
                // 查询是否在活动表中，取活动价格
                for (String s: strEndIndea) {
                    BigDecimal lsPrice = new BigDecimal(0);;
                    QueryWrapper<ActivityRoomPriceEntity> queryWrapper = new QueryWrapper<ActivityRoomPriceEntity>();
                    queryWrapper.eq("r_id",id).eq("delete_flag","0").eq("hd_time",s);
                    ActivityRoomPriceEntity hd = activityRoomPriceService.getOne(queryWrapper);
                    // 有就用活动价格 没有就用原始价格
                    if (hd != null){
                        lsPrice = lsPrice.add(hd.getPrice());
                    }else {
                        lsPrice = lsPrice.add(roomObj.getJg());
                    }
                    price = price.add(lsPrice);
                }

                // 只添加一次
                if (i == 0){
                    // 插入订单
                    order.setType(1L);// 1是酒店
                    Date date = new Date();
                    order.setCjTime(date);
                    SnowFlake idWorker = new SnowFlake(0, 0);
                    order.setNumber("JD"+String.valueOf(idWorker.nextId()));// 订单编号
                    order.setRoomId(order.getRoomIds());
                    order.setSpId(order.getRoomIds());
                    order.setSjrzTime(sjrzTime);
                    order.setLkTime(lkTime);
                    dao.insert(order);
                    // 记录订单日志表
                    sysOrderLogService.save(new SysOrderLogEntity(){{setOId(order.getId());setZt(7);setLogText("订单创建");}});
                }

                // 插入预约表
                for (String s: strEndIndea) {
                    RoomAppointmentEntity obj = new RoomAppointmentEntity();
                    obj.setPhone(order.getPhone());
                    obj.setMId(order.getMId());
                    obj.setRoomId(Integer.valueOf(id));
                    obj.setUserId(order.getUserId());
                    obj.setOId(order.getId());
                    obj.setTime(s);
                    roomAppointmentService.save(obj);
                }

                // 交易快照
                orderPriceDetailsService.save(new OrderPriceDetailsEntity(){{setOId(order.getId());setPrice(roomObj.getJg());setRId(id);setYdTime(sjrzTime);setMId(order.getMId());setTitle("酒店入住服务");}});
            }else {
                return R.error(SC_INSUFFICIENT_STORAGE,"订单并发");
            }
            i = 1;
        }
        OrderEntity updateObj = new OrderEntity();
        updateObj.setId(order.getId());
        updateObj.setMoney(price);
        this.update(updateObj);
        // 自动取消订单
        autoCancel(order);
        return R.ok().put("number",order.getNumber()).put("orderId",order.getId());
    }

    /**
     * 民宿下单保存
     */
    @Transactional
    @RequestMapping("/msSave")
    public R msSave(OrderDto order) throws ParseException {
        String[] ids = order.getRoomIds().split(",");
        String[] strings = order.getYdTime().split(","); // 包含离店时间的日期
        String sjrzTime = order.getYdTime().substring(0,order.getYdTime().lastIndexOf(",")); // 实际入驻时间
        String lkTime = order.getYdTime().substring((order.getYdTime().lastIndexOf(",")+1)); // 实际离店时间
        String[] strEndIndea = sjrzTime.split(",");
        int i = 0;
        BigDecimal price = new BigDecimal(0);
        for (String id: ids) {
            // 查询预约表中是否有预定的，加二重锁
            RoomAppointmentEntity f =  roomAppointmentService.selectByYdTime(order.getYdTime(),Integer.valueOf(id));
            if (f == null){
                QueryWrapper<MerchantRoomEntity> queryRoomWrapper = new QueryWrapper<MerchantRoomEntity>();
                queryRoomWrapper.eq("id",id).eq("delete_flag","0").eq("status",0);
                MerchantRoomEntity roomObj=  merchantRoomService.getOne(queryRoomWrapper);
                // 查询是否在活动表中，取活动价格
                for (String s: strEndIndea) {
                    BigDecimal lsPrice = new BigDecimal(0);;
                    QueryWrapper<ActivityRoomPriceEntity> queryWrapper = new QueryWrapper<ActivityRoomPriceEntity>();
                    queryWrapper.eq("r_id",id).eq("delete_flag","0").eq("hd_time",s);
                    ActivityRoomPriceEntity hd = activityRoomPriceService.getOne(queryWrapper);
                    // 有就用活动价格 没有就用原始价格
                    if (hd != null){
                        lsPrice = lsPrice.add(hd.getPrice());
                    }else {
                        lsPrice = lsPrice.add(roomObj.getJg());
                    }
                    price = price.add(lsPrice);
                }
                // 只添加一次
                if (i == 0){
                    // 插入订单
                    order.setType(2L);// 1是民宿
                    Date date = new Date();
                    order.setCjTime(date);
                    SnowFlake idWorker = new SnowFlake(0, 0);
                    order.setNumber("MS"+String.valueOf(idWorker.nextId()));// 订单编号
                    order.setRoomId(order.getRoomIds());
                    order.setSpId(order.getRoomIds());
                    order.setSjrzTime(sjrzTime);
                    order.setLkTime(lkTime);
                    dao.insert(order);
                    // 记录订单日志表
                    sysOrderLogService.save(new SysOrderLogEntity(){{setOId(order.getId());setZt(7);setLogText("订单创建");}});
                }

                // 插入预约表
                for (String s: strEndIndea) {
                    RoomAppointmentEntity obj = new RoomAppointmentEntity();
                    obj.setPhone(order.getPhone());
                    obj.setMId(order.getMId());
                    obj.setRoomId(Integer.valueOf(id));
                    obj.setUserId(order.getUserId());
                    obj.setOId(order.getId());
                    obj.setTime(s);
                    roomAppointmentService.save(obj);
                }

                // 交易快照
                orderPriceDetailsService.save(new OrderPriceDetailsEntity(){{setOId(order.getId());setPrice(roomObj.getJg());setRId(id);setYdTime(sjrzTime);setMId(order.getMId());setTitle("民宿入住服务");}});
            }else {
                return R.error(SC_INSUFFICIENT_STORAGE,"订单并发");
            }
            i = 1;
        }
        OrderEntity updateObj = new OrderEntity();
        updateObj.setId(order.getId());
        updateObj.setMoney(price);
        this.update(updateObj);
        // 自动取消订单
        autoCancel(order);
        return R.ok().put("number",order.getNumber()).put("orderId",order.getId());
    }


    /**
     * 餐饮下单保存
     */
    @Transactional
    @RequestMapping("/cySave")
    public R cySave(OrderDto order) throws ParseException {
        // 价格
        CateringEntity catering = cateringService.getById(order.getSpId());
        BigDecimal price = new BigDecimal(0); // 总价
        price = catering.getDj().multiply(BigDecimal.valueOf(order.getSl())); // 单价*数量

        //处理截止时间
        CateringEntity c = cateringService.getById(order.getSpId());
        Date date = new Date();
        order.setCjTime(date);
        Calendar calendar = Calendar.getInstance(); //日历时间工具类实例化创建，取得当前时间初值
        calendar.setTime(order.getCjTime());  //覆盖掉当前时间
        calendar.add(Calendar.DATE, c.getYxq()-1); // 获得有效期-1天 从当天开始算

        // 插入订单
        order.setType(4L);// 4是餐饮
        order.setMoney(price);
        order.setJzsj(calendar.getTime());
        SnowFlake idWorker = new SnowFlake(0, 0);
        order.setNumber("CY"+String.valueOf(idWorker.nextId()));// 订单编号
        dao.insert(order);
        // 记录订单日志表
        sysOrderLogService.save(new SysOrderLogEntity(){{setOId(order.getId());setZt(7);setLogText("订单创建");}});

        // 交易快照
        orderPriceDetailsService.save(new OrderPriceDetailsEntity(){{setOId(order.getId());setPrice(order.getMoney());setMId(order.getMId());setSpId(Integer.valueOf(order.getSpId()));
            setSl(order.getSl());setDj(catering.getDj());setTitle(catering.getTitle());}});
        return R.ok().put("number",order.getNumber()).put("orderId",order.getId());
    }

    /**
     * 文创下单保存
     */
    @Transactional
    @RequestMapping("/wcSave")
    public R wcSave(OrderDto order) throws ParseException {
        CreativeGoodsEntity creativeGoods = creativeGoodsService.getById(order.getSpId());
        // 乐观锁
        if (order.getVersion().equals(creativeGoods.getVersion())){
            // 价格
            BigDecimal price = new BigDecimal(0); // 总价
            price = creativeGoods.getDj().multiply(BigDecimal.valueOf(order.getSl())); // 单价*数量

            // 插入订单
            Date date = new Date();
            order.setCjTime(date);
            order.setType(3L);// 3是文创
            order.setMoney(price);
            SnowFlake idWorker = new SnowFlake(0, 0);
            order.setNumber("WC"+String.valueOf(idWorker.nextId()));// 订单编号
            order.setMId(40);
            dao.insert(order);
            // 记录订单日志表
            sysOrderLogService.save(new SysOrderLogEntity(){{setOId(order.getId());setZt(7);setLogText("订单创建");}});

            // 交易快照
            orderPriceDetailsService.save(new OrderPriceDetailsEntity(){{setOId(order.getId());setPrice(order.getMoney());setMId(order.getMId());setSpId(Integer.valueOf(order.getSpId()));
                setSl(order.getSl());setDj(creativeGoods.getDj());setTitle(creativeGoods.getTitle());}});

            // 操作版本
            CreativeGoodsEntity c = new CreativeGoodsEntity();
            c.setId(Integer.valueOf(order.getSpId()));
            c.setVersion(creativeGoods.getVersion()+1);
            c.setSl(creativeGoods.getSl()-order.getSl());
            creativeGoodsService.updateById(c);
            autoCancel(order);
            return R.ok().put("number",order.getNumber()).put("orderId",order.getId());
        }
        return R.error(SC_INSUFFICIENT_STORAGE,"订单并发");
    }


    /**
     * 票务下单保存
     */
    @Transactional
    @RequestMapping("/pwSave")
    public R pwSave(OrderDto order) throws ParseException {
        //return R.error();

        // 验证身份证
        IDCardValidator isSfz = new IDCardValidator();

        //order.setSl(1);// 暂时数量写死
        if (!isSfz.validate(order.getSfzhm())){
            return R.error(444,"身份证不合法");
        }

        // 价格
        BigDecimal price = null; // 总价

        if ("2054432".equals(order.getMpId())){
            order.setText("荷园画舫船票");
            price = BigDecimal.valueOf(30);
        }else if("2063674".equals(order.getMpId())){
            order.setText("大官画舫船票");
            price = BigDecimal.valueOf(50);
        }else if("2054399".equals(order.getMpId())){
            order.setText("微山岛门票");
            price = BigDecimal.valueOf(100);
        }
        price = price.multiply(BigDecimal.valueOf(order.getSl())); // 单价*数量


        // 插入订单
        Date date = new Date();
        order.setCjTime(date);
        order.setType(5L);// 5是票务
        order.setMoney(price);
        SnowFlake idWorker = new SnowFlake(0, 0);
        order.setNumber("PW"+String.valueOf(idWorker.nextId()));// 订单编号
        order.setMId(40);
        dao.insert(order);
        // 记录订单日志表
        sysOrderLogService.save(new SysOrderLogEntity(){{setOId(order.getId());setZt(7);setLogText("订单创建");}});

        // 交易快照
        orderPriceDetailsService.save(new OrderPriceDetailsEntity(){{setOId(order.getId());setPrice(order.getMoney());setMId(order.getMId());
            setSl(1);setDj(order.getMoney());setTitle("票务");}});

        autoCancel(order);
        return R.ok().put("number",order.getNumber()).put("orderId",order.getId());
    }


    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(OrderEntity order){
        orderService.updateById(order);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(Integer[] ids){
        orderService.removeByIds(Arrays.asList(ids));
        return R.ok();
    }

    /**
     * 自动取消订单
     */
    public void autoCancel(OrderDto order) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime(order.getCjTime());
        cal.add(Calendar.MINUTE, 30); // 自动取消时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = sdf.format(cal.getTime()); //Calendar转字符串时间格式
        //创建定时任务log
        sysOrderTaskService.save(new SysOrderTaskEntity(){{setOId(order.getId());setCancelTime(String.valueOf(str));setUserId(order.getUserId());}});
        Timer timer = new Timer();
        timer.schedule(new OrderTask(order), cal.getTime());
    }

    /**
     * 导游结束改变状态
     */
    public void DyUpdateZt(OrderDto order) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime(order.getCjTime());
        cal.add(Calendar.MINUTE, 130); // 自动取消时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = sdf.format(cal.getTime()); //Calendar转字符串时间格式
        //创建定时任务log
        sysOrderTaskService.save(new SysOrderTaskEntity(){{setOId(order.getId());setCancelTime(String.valueOf(str));setUserId(order.getUserId());}});
        Timer timer = new Timer();
        timer.schedule(new OrderDyTask(order), cal.getTime());
    }

    /**
     * 订单明细
     */
    @RequestMapping("/selectOrderDetailed")
    public R selectOrderDetailed(OrderDto order){
        return R.ok().put("order",orderService.selectOrderDetailed(order));
    }

    /**
     * 自动完成订单
     */
//    @Scheduled(cron = "0 50 23 ? * * ") // cron表达式
    @Transactional
    //@RequestMapping("/test")
    public void autoOrder(){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = new Date();
        String nowString = dateFormat.format(date1);
        QueryWrapper<OrderEntity> queryRoomWrapper = new QueryWrapper<OrderEntity>();
        queryRoomWrapper.in("zt","6").eq("delete_flag","0").eq("lk_time",nowString);
        List<OrderEntity> obj = orderService.list(queryRoomWrapper);
        List<String> oIds = new ArrayList<>();
        for (OrderEntity o:obj) {
            // 更改商家余额
            MerchantEntity mObj = merchantService.getById(o.getMId());
            MerchantEntity m = new MerchantEntity();
            m.setId(o.getMId());
            BigDecimal wallet = o.getMoney().multiply(mObj.getProportion()); // 此笔订单的抽额 订单总金额 * 抽佣比例 = 平台留存金额
            BigDecimal walletChange = o.getMoney().subtract(wallet); // 变动金额  订单总金额 - 平台留存金额 = 此次变动金额
            BigDecimal walletAfter = mObj.getWallet().add(walletChange); // 变动后金额 商家现存余额 + 变动金额 = 变动后金额

            m.setWallet(walletAfter);
            merchantService.updateById(m);
            // 添加商家余额日志
            MerchantWalletLogEntity walletLog = new MerchantWalletLogEntity();
            walletLog.setWalletUp(mObj.getWallet());// 变动前金额
            walletLog.setWalletAfter(walletAfter);// 变动后金额
            walletLog.setWalletChange(walletChange);// 变动金额
            walletLog.setOId(o.getId());
            walletLog.setMId(o.getMId());
            walletLog.setType(1); // 1增加 2消减
            walletLog.setProportion(mObj.getProportion()); // 当前商家抽佣比例
            walletLog.setProportionMoney(wallet); // 此次平台留存金额 根据上方抽佣比例计算得出
            merchantWalletLogService.save(walletLog);

            // 更改订单状态
            o.setZt(4L);
            orderService.updateById(o);
            // 添加日志
            sysOrderLogService.save(new SysOrderLogEntity(){{setOId(o.getId());setLogText("订单已完成");setText("系统自动");setZt(4);}});
            oIds.add(String.valueOf(o.getId()));
        }
        // 记录任务日志
        OrderJobLogEntity ojl = new OrderJobLogEntity();
        ojl.setText("系统自动");
        ojl.setOIds(oIds.toString());
        ojl.setType(2);
        orderJobLogService.save(ojl);
        System.out.println("定时执行");
    }

    /**
     * 订单明细 餐饮
     */
    @RequestMapping("/selectCyOrderDetailed")
    public R selectCyOrderDetailed(OrderDto order){
        return R.ok().put("order",orderService.selectCyOrderDetailed(order));
    }
    /**
     * 订单明细 票务
     */
    @RequestMapping("/selectPwOrderDetailed")
    public R selectPwOrderDetailed(OrderEntity order){
        return R.ok().put("order",orderService.getById(order));
    }

    /**
     * 订单明细 文创
     */
    @RequestMapping("/selectWcOrderDetailed")
    public R selectWcOrderDetailed(OrderDto order){
        return R.ok().put("order",orderService.selectWcOrderDetailed(order));
    }

    /**
     * 订单明细 导游
     */
    @RequestMapping("/selectDyOrderDetailed")
    public R selectDyOrderDetailed(OrderDto order){
        return R.ok().put("order",orderService.selectDyOrderDetailed(order));
    }

    /**
     * 判断订单是否付款
     */
    @RequestMapping("/ifFk")
    public R ifFk(OrderDto order){
        OrderEntity o = orderService.getById(order.getId());
        int f = 0;
        if (o.getZt() == 1){
            f = 1;
        }
        return R.ok().put("f",f);
    }

    /**
     * 餐饮订单分红
     */
    @RequestMapping("/orderBonus")
    public R orderBonus(String num){
        QueryWrapper<OrderEntity> queryRoomWrapper = new QueryWrapper<OrderEntity>();
        queryRoomWrapper.eq("number",num).eq("zt","4").eq("type","4");
        OrderEntity o = orderService.getOne(queryRoomWrapper);
        if (o == null){
            return R.error("此订单不存在或已完成");
        }
        // 更改商家余额
        MerchantEntity mObj = merchantService.getById(o.getMId());
        MerchantEntity m = new MerchantEntity();
        m.setId(o.getMId());
        BigDecimal wallet = o.getMoney().multiply(mObj.getProportion()); // 此笔订单的抽额 [订单总金额 * 抽佣比例 = 平台留存金额]
        BigDecimal walletChange = o.getMoney().subtract(wallet); // 变动金额  [订单总金额 - 平台留存金额 = 此次变动金额]
        BigDecimal walletAfter = mObj.getWallet().add(walletChange); // 变动后金额 [商家现存余额 + 变动金额 = 变动后金额]

        m.setWallet(walletAfter);
        merchantService.updateById(m);
        // 添加商家余额日志
        MerchantWalletLogEntity walletLog = new MerchantWalletLogEntity();
        walletLog.setWalletUp(mObj.getWallet());// 变动前金额
        walletLog.setWalletAfter(walletAfter);// 变动后金额
        walletLog.setWalletChange(walletChange);// 变动金额
        walletLog.setOId(o.getId());
        walletLog.setMId(o.getMId());
        walletLog.setType(1); // 1增加 2消减
        walletLog.setProportion(mObj.getProportion()); // 当前商家抽佣比例
        walletLog.setProportionMoney(wallet); // 此次平台留存金额 根据上方抽佣比例计算得出
        merchantWalletLogService.save(walletLog);

        // 添加日志
        sysOrderLogService.save(new SysOrderLogEntity(){{setOId(o.getId());setLogText("订单已完成");setText("商家验券后分成");setZt(4);}});
        // 记录任务日志
        orderJobLogService.save(new OrderJobLogEntity(){{setText("餐饮分红，扫码触发");setOIds(String.valueOf(o.getId()));setType(1);}});
        return R.ok();
    }

    /**
     * 退款申请 酒店民宿文创票务用
     */
    @Transactional
    @RequestMapping("/sqtk")
    public R sqtk(OrderDto order){
        // 修改订单状态
        Date date = new Date();
        OrderEntity o = new OrderEntity();
        o.setId(order.getId());
        o.setZt(3L);
        o.setTkTime(date);
        o.setTkZt(1L);
        orderService.updateById(o);
        // 记录任务日志
        sysOrderLogService.save(new SysOrderLogEntity(){{setLogText("用户申请退款");setText("用户申请退款");setOId(o.getId());setZt(2);}});
        return R.ok();
    }


    /**
     * 退款修改
     * 同意 或 拒绝
     */
    @Transactional
    @RequestMapping("/tkUpdate")
    public R tkUpdate(OrderDto order){
        SysOrderLogEntity orderLog = new SysOrderLogEntity();
        OrderEntity obj = new OrderEntity();

        if (order.getTkZt() == 2){
            WxTkUtil wxtk = new WxTkUtil();
            OrderEntity o = orderService.getById(order);
            BigDecimal price = new BigDecimal(String.valueOf(o.getMoney())).multiply(new BigDecimal(100));
            SnowFlake idWorker = new SnowFlake(0, 0);
            // 调用微信退款申请
            Map<String, String> ttt = wxtk.refund(o.getNumber(),"TK"+String.valueOf(idWorker.nextId()), String.valueOf(price.intValue()),String.valueOf(price.intValue()),"REFUND_SOURCE_UNSETTLED_FUNDS");
            System.out.println("==========================================================申请返回信息"+ttt.get("result_code"));
            if (ttt.get("result_code") !=null && "SUCCESS".equals(ttt.get("result_code"))){
                // 退款成功
                // 这里就写逻辑，当然，如果不需要写逻辑的话，可以直接吧if else 删掉也是可以直接跑起来的
                obj.setZt(11L);
                orderLog.setLogText("同意退款");
                orderLog.setZt(3);
            }else {
                // 退款失败
            }

        }else if (order.getTkZt() == 3){
            obj.setZt(10L);
            orderLog.setLogText("拒绝退款");
            orderLog.setZt(12);
        }

        Date date = new Date();
        obj.setId(order.getId());
        obj.setTkZt(order.getTkZt());
        obj.setTkhzTime(date);
        orderService.updateById(obj);

        orderLog.setOId(order.getId());
        sysOrderLogService.save(orderLog);

        return R.ok();
    }

    /**
     * 退款回调
     */
    @Transactional
    @RequestMapping("/tkhd")
    public void tkhd(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";

        Map map = PayUtil.doXMLParse(notityXml);

        // 解密 req_info
        Map mapJm = xmlToMap(getRefundDecrypt((String) map.get("req_info"),WechatConfig.key));
        QueryWrapper<OrderEntity> queryWrapper = new QueryWrapper<OrderEntity>();
        queryWrapper.eq("number", mapJm.get("out_trade_no"));
        OrderEntity orderEntity = orderService.getOne(queryWrapper);

        System.out.println("========================解密"+mapJm);


        if ("SUCCESS".equals(map.get("return_code"))) {
            // 查询出订单，而且未付款，继续往下走流程
            if (orderEntity != null && 3 == orderEntity.getZt()) {
                //验证签名是否正确
                Map<String, String> validParams = PayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数
                String prestr = PayUtil.createLinkString(validParams);
                //根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
                if (PayUtil.verify(prestr, (String) map.get("sign"), WechatConfig.key, "utf-8")) {
                    /**此处添加自己的业务逻辑代码start**/
                    // 记录订单日志表
                    SysOrderLogEntity oLog = new SysOrderLogEntity();
                    oLog.setLogText("订单退款成功");
                    oLog.setOId(orderEntity.getId());
                    oLog.setZt(6);
                    sysOrderLogService.save(oLog);

                    if (orderEntity.getType() == 1 || orderEntity.getType() == 2) {
                        // 取消预约表
                        String[] ids = orderEntity.getSpId().split(",");
                        for (String id: ids) {
                            OrderDto obj = new OrderDto();
                            BeanUtils.copyProperties(orderEntity, obj);
                            obj.setZt(1L);// 1是取消预约
                            obj.setRoomId(id);
                            roomAppointmentService.cancelReservation(obj);
                        }
                    }
//                        if (2 == orderEntity.getZt()) {
//                            // 如果为订单状态2 订单错发 改为1 待确认
//                            orderEntity.setZt(1L);
//                            oLog.setText("错发订单");
//                            oLog.setLogText("待酒店确认");
//                            oLog.setZt(10);
//                        }else if (0 == orderEntity.getZt()) {
//                            // 订单表改为确认完成
//                            orderEntity.setZt(6L);
//                            oLog.setLogText("酒店确认完成");
//                            oLog.setZt(8);
//                        }
//                        // 再次记录记录订单日志表
//                        sysOrderLogService.save(oLog);
//                    }
//                    if (orderEntity.getType() == 4){ // 餐饮
//                        orderEntity.setZt(1L);
//                    }
//                    if (orderEntity.getType() == 3){ // 文创
//                        orderEntity.setZt(1L);
//                        CreativeGoodsEntity obj = creativeGoodsService.getById(orderEntity.getSpId());
//                        CreativeGoodsEntity c = new CreativeGoodsEntity();
//                        c.setId(obj.getId());
//                        c.setSl(obj.getSl()-orderEntity.getSl());
//                        creativeGoodsService.updateById(c);
//                    }
//                    // 修改订单
                    OrderEntity orderObj = new OrderEntity();
                    orderObj.setId(orderEntity.getId());
                    orderObj.setZt(7L);
                    orderEntity.setTkdh((String) map.get("out_refund_no"));
                    orderService.updateById(orderEntity);

                    // 记录任务日志
                    sysOrderLogService.save(new SysOrderLogEntity(){{setLogText("退款已到账");setText("退款已到账");setOId(orderObj.getId());setZt(13);}});


                    //注意要判断微信支付重复回调，支付成功后微信会重复的进行回调
                    /**此处添加自己的业务逻辑代码end**/
                    //通知微信服务器已经支付成功
                }
            }
            resXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        } else {
            resXml = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml>";
        }

        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

    /**
     * 确认收货 文创用
     */
    @Transactional
    @RequestMapping("/qrsh")
    public R qrsh(OrderDto order){
        // 修改订单状态
        OrderEntity o = new OrderEntity();
        o.setId(order.getId());
        o.setZt(4L);
        orderService.updateById(o);
        // 记录任务日志
        sysOrderLogService.save(new SysOrderLogEntity(){{setLogText("用户确认收货");setText("用户确认收货");setOId(o.getId());setZt(4);}});
        return R.ok();
    }


    /**
     * 退款修改 酒民餐 关塞川 暴露接口
     */
    @Transactional
    @RequestMapping("/cyTkUpdate")
    public R CyTkUpdate(OrderDto order){
        SysOrderLogEntity orderLog = new SysOrderLogEntity();
        OrderEntity obj = new OrderEntity();

        if (order.getTkZt() == 2){
            WxTkUtil wxtk = new WxTkUtil();
            OrderEntity o = orderService.getById(order);
            BigDecimal price = new BigDecimal(String.valueOf(o.getMoney())).multiply(new BigDecimal(100));
            SnowFlake idWorker = new SnowFlake(0, 0);
            // 调用微信退款申请
            wxtk.refund(o.getNumber(),"TK"+String.valueOf(idWorker.nextId()), String.valueOf(price.intValue()),String.valueOf(price.intValue()),"REFUND_SOURCE_UNSETTLED_FUNDS");
            obj.setZt(11L);
            orderLog.setLogText("同意退款");
            orderLog.setZt(3);
        }else if (order.getTkZt() == 3){
            obj.setZt(10L);
            orderLog.setLogText("拒绝退款");
            orderLog.setZt(12);
        }

        Date date = new Date();
        obj.setId(order.getId());
        obj.setTkZt(order.getTkZt());
        obj.setTkhzTime(date);
        orderService.updateById(obj);

        orderLog.setOId(order.getId());
        sysOrderLogService.save(orderLog);

        return R.ok();
    }

    /**
     * 退款进度
     */
    @Transactional
    @RequestMapping("/queryTkJd")
    public R queryTkJd(OrderDto order){
        QueryWrapper<SysOrderLogEntity> queryWrapper = new QueryWrapper<SysOrderLogEntity>();
        queryWrapper.in("zt", 2,3,12,13).eq("o_id",order.getId()).orderBy(true,false,"cj_time");
        List<SysOrderLogEntity> list = sysOrderLogService.list(queryWrapper);

        List<Map<String,String>> listMap = new ArrayList<>();

        for (SysOrderLogEntity obj:list) {
            Map map = new HashMap<>();
            map.put("title",obj.getLogText());
            map.put("desc",obj.getCjTime());
            listMap.add(map);
        }
        return R.ok().put("data",listMap);
    }

    /**
     * 下单回调
     */
    @RequestMapping("/xdhd")
    @ResponseBody
    public String xdhd(OrderDto order){

        return "success";
    }

    /**
     * 验票回调
     */
    @RequestMapping("/yphd")
    @ResponseBody
    public String yphd(PFTOrderResult pft){
        System.out.println("Order16U"+pft.getOrder16U()+"OrderState"+pft.getOrderState()+"VerifyCode"+pft.getVerifyCode()+"Tnumber"+pft.getTnumber()+"orderCall"+pft.getOrderCall()+"actionTime"+pft.getActionTime()+"allCheckNum"+pft.getAllCheckNum()+"Source"+pft.getSource());
        return "success";
    }

    /**
     * 票付通回调
     */
    @RequestMapping("/pwTkhd")
    @ResponseBody
    public String pwTkhd(@RequestBody PFTOrderResult pft){
        System.out.println("回调回调回调回调回调回调解析完的数据：" + JSON.toJSONString(pft)+"\n");
        System.out.println("回调回调回调回调回调回调解析完的数据：" + JSON.toJSONString(pft));
        if ("1".equals(pft.getOrderState())){
            OrderEntity o = new OrderEntity();
            o.setId(Integer.valueOf(pft.getOrderCall()));
            o.setZt(4L);
            orderService.updateById(o);
            // 记录任务日志
            sysOrderLogService.save(new SysOrderLogEntity(){{setLogText("验证完毕");setText("已验票");setOId(o.getId());setZt(4);}});
        }
        return "success";
    }


    /**
     * 票付通产品列表
     */
    @RequestMapping("/pwfCpList")
    public String pwfCpList(){
        pw pw =new pw();
        pw.product();
        return "success";
    }

    /**
     * 导游下单保存
     */
    @Transactional
    @RequestMapping("/dySave")
    public R dySave(OrderDto order) throws ParseException {
        DybEntity dybEntity = dybService.getById(order.getSpId());
        // 乐观锁
        if (order.getVersion().equals(dybEntity.getVersion())){
           /* // 价格
            BigDecimal price = new BigDecimal(0); // 总价
            price = creativeGoods.getDj().multiply(BigDecimal.valueOf(order.getSl())); // 单价*数量*/

            // 插入订单
            Date date = new Date();
            order.setCjTime(date);
            order.setType(6L);// 6是导游
            order.setMoney(dybEntity.getMoney());
            SnowFlake idWorker = new SnowFlake(0, 0);
            order.setNumber("DY"+String.valueOf(idWorker.nextId()));// 订单编号
            order.setMId(40);
            dao.insert(order);
            // 记录订单日志表
            sysOrderLogService.save(new SysOrderLogEntity(){{setOId(order.getId());setZt(7);setLogText("订单创建");}});

            // 交易快照
            orderPriceDetailsService.save
                    (new OrderPriceDetailsEntity(){{setOId(order.getId());setPrice(order.getMoney());setMId(order.getMId());
                        setSpId(Integer.valueOf(order.getSpId()));
                        setSl(order.getSl());setDj(dybEntity.getMoney());}});

            // 操作版本
            DybEntity d = new DybEntity();
            d.setId(Integer.valueOf(order.getSpId()));
            d.setVersion(dybEntity.getVersion()+1);
            dybService.updateById(d);
            // 判断订单状态
            autoCancel(order);
            // 判断定时取消
            DyUpdateZt(order);
            return R.ok().put("number",order.getNumber()).put("orderId",order.getId());
        }
        return R.error(SC_INSUFFICIENT_STORAGE,"订单并发");
    }

}
